package com.zjuee.web.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zjuee.gateway.utils.SecurityUtil;
import com.zjuee.web.auth.mapper.OrgMapper;
import com.zjuee.base.bean.response.CommonResultCode;
import com.zjuee.base.exception.BaseException;
import com.zjuee.base.model.AuthUser;
import com.zjuee.base.model.common.auth.Org;
import com.zjuee.base.utils.CommonUtil;
import com.zjuee.service.auth.service.OrgService;
import com.zjuee.service.auth.vo.OrgVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 组织机构服务接口实现类
 *
 * @author wu liang
 * @since 1.0
 */
@Slf4j
@Service
public class OrgServiceImpl implements OrgService {

    @Resource
    private OrgMapper orgMapper;


    @Override
    @Transactional
    public Long add(OrgVo type) {
        Org org = new Org();
        BeanUtils.copyProperties(type, org);
        //补充levelCode ,并校验父节点
        if (org.getParentId() != null && org.getParentId() != 0) {
            LambdaQueryWrapper<Org> queryWrapper = Wrappers.<Org>query().lambda();
            queryWrapper.eq(Org::getId, org.getParentId());
            Org parentOrg = orgMapper.selectOne(queryWrapper);
            if (parentOrg == null) {
                throw new BaseException(CommonResultCode.CONSUMER_ERR, "父节点组织机构不存在");
            }
            //根据父节点类型，设置子节点类型
            org.setOrgType(Byte.valueOf("1"));

            org.setLevelCode(getMaxLevelCode(parentOrg.getLevelCode()));
        }else {
            org.setParentId(1L);
            org.setLevelCode(getMaxLevelCode("000"));
            org.setOrgType(Byte.valueOf("1"));
        }

        AuthUser authUser = SecurityUtil.getOnlineUser();
        org.setCreateId(authUser.getId());
        org.setGmtCreate(new Date());
        org.setModifyId(authUser.getId());
        org.setGmtModify(new Date());

        orgMapper.insert(org);
        return org.getId();
    }

    @Override
    public Org selectById(Long id) {
        return orgMapper.selectById(id);
    }

    @Override
    public List<Org> subList(Long parentId) {
        //查询子集
        LambdaQueryWrapper<Org> queryWrapper = Wrappers.<Org>query().lambda();
        queryWrapper.eq(Org::getParentId, parentId);
        return orgMapper.selectList(queryWrapper);
    }

    @Override
    public Boolean update(Org org) {
//        org.setModifyId(loginDto.getUserId());
        org.setGmtModify(new Date());
        return orgMapper.updateById(org) > 0;
    }

    @Override
    @Transactional
    public Boolean delete(Long id) {
        Org org = selectById(id);
        if (org==null){
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "组织机构不存在");
        }
        if (0 == org.getParentId()){
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "此节点为顶层节点，不可手动删除");
        }
        //查询子集 - 若有就不能删除
        LambdaQueryWrapper<Org> queryWrapper = Wrappers.<Org>query().lambda();
        queryWrapper.eq(Org::getParentId, id);
        Integer count = orgMapper.selectCount(queryWrapper);
        if(count > 0){
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "存在子集，不可删除");
        }

        return orgMapper.deleteById(id) > 0;
    }

    @Override
    public List<OrgVo> govOrg() {
        List<OrgVo> orgVoList = orgMapper.findGovOrg();
        return CommonUtil.buildTree(orgVoList, OrgVo::getLevelCode, OrgVo::getChildren);
    }

    //获取下一层 下一个levelCode
    private String getMaxLevelCode(String prefix) {
        prefix = prefix == null ? "" : prefix;
        String levelCodeFormat = prefix + "___";
        String levelStr = orgMapper.getMaxLevelCode(levelCodeFormat);

        if (StringUtils.isBlank(levelStr)) {
            return prefix + "000";
        }

        String codeStr = levelStr.substring(prefix.length());
        int newCode = Integer.parseInt(codeStr) + 1;
        String temp = "000" + newCode;

        return prefix + temp.substring(temp.length() - 3);
    }
}
